﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MethodWorx.CMS.Content;
using MethodWorx.Core.Linq;
using System.Data.Linq;

namespace MethodWorx.CMS.Linq
{
    public class LinqPageTemplateRepository : LinqRepository<LinqPageTemplate, PageTemplate>, IPageTemplateRepository
    {
        private PageTemplateRepository inner;

        public LinqPageTemplateRepository(DataContext context)
            : base(context)
        {
            this.source = this.source.Where(s => s.Deleted == false);
            this.inner = new PageTemplateRepository(this.source);
        }


        public PageTemplate FindByName(string name)
        {
            return inner.FindByName(name);
        }

        public override object CreateInstance(Type type)
        {
            if (type == typeof(PageTemplate))
                return new LinqPageTemplate();
            else if (type == typeof(Property))
                return new LinqPageTemplateProperty();
            else if (type == typeof(PageTemplateConstraint))
                return new LinqPageTemplateConstraint();
            else
                throw new NotSupportedException("Can not create type of: " + type.FullName + " with the PageTemplate repository");
        }

        public PageTemplate FindRoot()
        {
            return inner.FindRoot();
        }

        public IEnumerable<PageTemplate> FindAbstract()
        {
            return inner.FindAbstract();
        }

        protected override void OnInsert(LinqPageTemplate entity)
        {
            this.PersistAggregate(entity);

            base.OnInsert(entity);
        }

        protected override void OnUpdate(LinqPageTemplate entity)
        {
            entity.Workflows = entity.Workflows;

            this.PersistAggregate(entity);

            base.OnUpdate(entity);
        }

        private void PersistAggregate(LinqPageTemplate entity)
        {
            foreach (var action in this.UpdateChildEntitySet(entity.ProxyPageTemplateConstraints, entity.PageTemplateConstraints,
                                    (ptc) => ptc.ParentTemplateId = entity.Id).ToList())
            {
                /*if (action.Type == RepositoryActionType.Deleted)
                    entity.ProxyPageTemplateConstraints.Remove(action.Entity);
                else if(action.Type == RepositoryActionType.Inserted)
                    entity.ProxyPageTemplateConstraints.Add(action.Entity);*/
            }

            foreach (var action in this.UpdateChildEntitySet(entity.ProxyContentTemplateConstraints, entity.ContentTemplateConstraints,
                                 (ptc) => ptc.ParentTemplateId = entity.Id).ToList())
            {
                /*if (action.Type == RepositoryActionType.Deleted)
                    entity.ProxyPageTemplateConstraints.Remove(action.Entity);
                else if(action.Type == RepositoryActionType.Inserted)
                    entity.ProxyPageTemplateConstraints.Add(action.Entity);*/
            }

            foreach (var action in this.UpdateChildEntitySet(entity.ProxyProperties, entity.Properties,
                               (ptc) => ptc.PageTemplateId = entity.Id).ToList())
            {
                /*if (action.Type == RepositoryActionType.Deleted)
                    entity.ProxyPageTemplateConstraints.Remove(action.Entity);
                else if(action.Type == RepositoryActionType.Inserted)
                    entity.ProxyPageTemplateConstraints.Add(action.Entity);*/
            }
        }


        public PageTemplate FindAbstractPageTemplateByName(string name)
        {
            return this.source.FirstOrDefault(pt => pt.Abstract && pt.Name == name);
        }

        #region IPageTemplateRepository Members


        public IEnumerable<PageTemplate> FindContainingContentTemplate(ContentTemplate contentTemplate)
        {
            return this.source.Cast<LinqPageTemplate>().Where(pt => pt.ProxyContentTemplateConstraints.Where(c => c.RelatedTemplateId == contentTemplate.Id).Any());
        }

        public IEnumerable<PageTemplate> FindContainingPageTemplate(PageTemplate pageTemplate)
        {
            return this.source.Cast<LinqPageTemplate>().Where(pt => pt.ProxyPageTemplateConstraints.Where(c => c.RelatedTemplateId == pageTemplate.Id).Any());
        }

        #endregion
    }
}
